﻿using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Doolin.MongoRepository
{
  public class FilterHelper
  {
    public static FilterDefinition<T> And<T>(params FilterDefinition<T>[] filters) where T : class, new()
    {
      return Builders<T>.Filter.And(filters);
    }
    public static FilterDefinition<T> Or<T>(params FilterDefinition<T>[] filters) where T : class, new()
    {
      return Builders<T>.Filter.Or(filters);
    }
    public static ProjectionDefinition<T> Projection<T>(string[] fields) where T : class, new()
    {
      ProjectionDefinitionBuilder<T> builderProjection = Builders<T>.Projection;
      ProjectionDefinition<T> projection = builderProjection.Include("_id");
      foreach (var field in fields)
        projection.Include(field);
      return projection;
    }
    public static FilterDefinition<T> IgnoreCaseFilter<T>(string field, string text) where T: class, new()
    {
      if (String.IsNullOrWhiteSpace(text)) return FilterDefinition<T>.Empty;
      FieldDefinition<T> f = field;
      var ex = new BsonRegularExpression(new Regex(@"^" + text + @"$",RegexOptions.IgnoreCase));
      FilterDefinition<T> filter = Builders<T>.Filter.Regex(f, ex);
      return filter;
    }
    public static FilterDefinition<T> RegexFilter<T>(string field, string keywords) where T : class, new()
    {
      if (String.IsNullOrWhiteSpace(keywords)) return FilterDefinition<T>.Empty;
      FieldDefinition<T> f = field;
      FilterDefinition<T> filter = Builders<T>.Filter.Regex(f, new BsonRegularExpression(new Regex(keywords, RegexOptions.IgnoreCase)));
      return filter;
    }
    public static FilterDefinition<T> RegexFilters<T>(string field, string[] keywords) where T : class, new()
    {
      if (keywords.Length <= 0) return FilterDefinition<T>.Empty;
      var filters = new List<FilterDefinition<T>>();
      foreach (var keyword in keywords)
      {
        var filter = RegexFilter<T>(field, keyword);
        if (filter != null)
          filters.Add(filter);
      }
      return Builders<T>.Filter.Or(filters);
    }
    public static FilterDefinition<T> RegexFilters<T>(string[] fields, string keywords) where T : class, new()
    {
      if (String.IsNullOrWhiteSpace(keywords)) return FilterDefinition<T>.Empty;
      if (fields.Length <= 0) return FilterDefinition<T>.Empty;
      var filters = new List<FilterDefinition<T>>();
      foreach (string field in fields)
      {
        var filter = RegexFilter<T>(field, keywords);
        if (filter != null)
          filters.Add(filter);
      }
      return Builders<T>.Filter.Or(filters);
    }

  }
}
